package com.niuwa.p2p.service.impl.filesystem;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.constant.FileSystemEnum;
import com.niuwa.p2p.core.file.ImageMagick;
import com.niuwa.p2p.core.file.NWFileGenerator;
import com.niuwa.p2p.core.utils.UUIDUtil;
import com.niuwa.p2p.dao.nwfile.NWFileDao;
import com.niuwa.p2p.entity.nwfile.NWFile;
import com.niuwa.p2p.service.filesystem.FileSystem;

@Service
public class FileSystemImpl implements FileSystem {

	@Autowired
	private NWFileDao nwFileDao;

	@Value("#{propertiesReader['system.waterImagePath']}")
	private String waterImagePath;

	@Value("#{propertiesReader['system.publicFilePath']}")
	private String PUBLIC_FOLDER;

	@Value("#{propertiesReader['system.privateFilePath']}")
	private String PRIVATE_FOLDER;

	@Value("#{propertiesReader['system.tempFilePath']}")
	private String TEMP_FOLDER;

	private final static float scaleSize = 0.95f;

	private final static float waterSize = 0.80f;

	private static Logger logger = Logger.getLogger(FileSystemImpl.class); // 日志记录

	// -scaleSize
	// 质量：设定jpeg图片输出质量，推荐采用80，此命令仅用于输出格式是jpg的情况，不应省略，省略的话默认质量是95，生成图片过大

	@Override
	public String savePublicFile(File file) throws Exception {
		String UUIDStr = "pl_" + UUIDUtil.getStringUUid();
		NWFile nwFile = NWFileGenerator.publicNWFilegenerate(file, UUIDStr);
		nwFileDao.saveFile(nwFile);
		return nwFile.getFileID();
	}

	@Override
	public String savePrivateFile(File file) throws Exception {
		String UUIDStr = "pr_" + UUIDUtil.getStringUUid();
		NWFile nwFile = NWFileGenerator.privateNWFilegenerate(file, UUIDStr);
		nwFileDao.saveFile(nwFile);
		return nwFile.getFileID();
	}

	@Override
	public File getFile(String fileID) throws Exception {
		NWFile nwFile = nwFileDao.getFile(fileID);
		if (null == nwFile) {
			return null;
		}
		return new File(nwFile.getFilePath() + File.separator
				+ nwFile.getFileID() + "." + nwFile.getFileType());
	}

	@Override
	public void deleteFile(String fileID) throws Exception {
		NWFile nwFile = nwFileDao.getFile(fileID);
		if (null == nwFile) {
			return;
		}
		nwFileDao.deleteFile(fileID);
		File file = new File(nwFile.getFilePath() + File.separator
				+ nwFile.getFileID() + "." + nwFile.getFileType());
		File tempfile = new File(nwFile.getTempFilePath() + File.separator
				+ nwFile.getFileID() + "." + nwFile.getFileType());
		if (file.exists())
			file.delete();
		if (tempfile.exists())
			tempfile.delete();
	}

	@Override
	public List<String> getImageFiles(String fileID) throws Exception {
		List<String> files = new ArrayList<String>();
		NWFile nwFile = nwFileDao.getFile(fileID);
		if (null == nwFile || !isImageFile(nwFile.getFileType())) {
			return null;
		}
		String originalImage = nwFile.getFileID();
		String middeImage = originalImage + "_midde";
		String smallImage = originalImage + "_small";
		files.add(originalImage);
		files.add(middeImage);
		files.add(smallImage);
		return files;
	}

	@Override
	public void deleteImageFiles(String fileID) throws Exception {
		NWFile nwFile = nwFileDao.getFile(fileID);
		if (null == nwFile || !isImageFile(nwFile.getFileType())) {
			return;
		}
		nwFileDao.deleteFile(fileID);
		File originalImage = new File(nwFile.getFilePath() + File.separator
				+ nwFile.getFileID() + "." + nwFile.getFileType());
		File middeImage = new File(nwFile.getFilePath() + File.separator
				+ nwFile.getFileID() + "_midde." + nwFile.getFileType());
		File smallImage = new File(nwFile.getFilePath() + File.separator
				+ nwFile.getFileID() + "_small." + nwFile.getFileType());
		File tempfile = new File(nwFile.getTempFilePath() + File.separator
				+ nwFile.getFileID() + "." + nwFile.getFileType());
		if (originalImage.exists())
			originalImage.delete();
		if (tempfile.exists())
			tempfile.delete();
		if (middeImage.exists())
			middeImage.delete();
		if (smallImage.exists())
			smallImage.delete();
	};

	@Override
	public String saveFileByStream(FileSystemEnum fileSystemEnum,
			InputStream is, String fileType) {
		String UUIDStr = null;
		String fileSavePath = null;
		String tempSavePath = null;
		if (fileSystemEnum == FileSystemEnum.PUBLIC) {// 公共
			UUIDStr = "pl_" + UUIDUtil.getStringUUid();
			fileSavePath = PUBLIC_FOLDER + File.separator + UUIDStr + "."
					+ fileType;
		} else {
			UUIDStr = "pr_" + UUIDUtil.getStringUUid();
			fileSavePath = PRIVATE_FOLDER + File.separator + UUIDStr + "."
					+ fileType;
		}
		tempSavePath = TEMP_FOLDER + File.separator + UUIDStr + "." + fileType;
		File fileTemp = new File(tempSavePath);
		File file = new File(fileSavePath);
		OutputStream os = null;
		InputStream in = null;
		try {
			os = new FileOutputStream(fileTemp);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
				os.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			os = new FileOutputStream(file);
			in = new FileInputStream(fileTemp);
			int bytesRead = 0;
			byte[] buffer = new byte[8192];
			while ((bytesRead = in.read(buffer, 0, 8192)) != -1) {
				os.write(buffer, 0, bytesRead);
				os.flush();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			os.close();
			is.close();
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		return UUIDStr;
	}

	public String saveFileByStream(FileSystemEnum fileSystemEnum,
			String strContent, String fileType) {
		ByteArrayInputStream stream = new ByteArrayInputStream(
				strContent.getBytes());
		return saveFileByStream(fileSystemEnum, stream, fileType);
	}

	/**
	 * 保存图片不打水印
	 */
	@Override
	public String saveImageFile(FileSystemEnum fileSystemEnum, File file)
			throws Exception {
		if (null == fileSystemEnum) {
			return null;
		}
		if (isImageFile(getFileType(file))) {
			if (fileSystemEnum == FileSystemEnum.PUBLIC) { // 公共
				// temp图和大图(原图)
				String UUIDStr = "pl_" + UUIDUtil.getStringUUid();
				NWFile nwFile = NWFileGenerator.publicNWFilegenerate(file,
						UUIDStr);
				logger.error("调试文件系统。。。。。。path:" + file.getPath());
				String originalImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "." + nwFile.getFileType();
				logger.error("调试文件系统。。。。。。originalImage:" + originalImage);
				// 压缩下图片大小
				ImageMagick.scaleImage(originalImage, originalImage, scaleSize);
				logger.error("我还没有出异常3......");
				// 中图
				String middeImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_midde." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, middeImage, 600, null);
				// 小图
				String smallImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_small." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, smallImage, 300, null);
				nwFileDao.saveFile(nwFile);
				return nwFile.getFileID();
			} else {
				// temp图和大图(原图)
				String UUIDStr = "pr_" + UUIDUtil.getStringUUid();
				NWFile nwFile = NWFileGenerator.privateNWFilegenerate(file,
						UUIDStr);
				String originalImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "." + nwFile.getFileType();
				// 压缩下图片大小
				ImageMagick.scaleImage(originalImage, originalImage, scaleSize);
				// 中图
				String middeImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_midde." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, middeImage, 600, null);
				// 小图
				String smallImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_small." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, smallImage, 300, null);
				nwFileDao.saveFile(nwFile);
				return nwFile.getFileID();
			}
		}

		return null;
	}

	/**
	 * 保存图片打文本水印
	 */
	/*
	 * @Override public String saveImageWatermark(FileSystemEnum fileSystemEnum,
	 * File file, String text) throws Exception { if (null == fileSystemEnum) {
	 * return null; } if (isImageFile(getFileType(file))) { if (fileSystemEnum
	 * == FileSystemEnum.PUBLIC) { // 公共 String UUIDStr = "pl_" +
	 * UUIDUtil.getStringUUid(); NWFile nwFile =
	 * NWFileGenerator.publicNWFilegenerate(file, UUIDStr); //
	 * 原始图片打上水印，temp图片不打水印 String originalImage = nwFile.getFilePath() +
	 * File.separator + nwFile.getFileID() + "." + nwFile.getFileType();
	 * GraphicsMagick.addImgText(originalImage, text);// 已经打上水印 // 压缩下图片大小
	 * GraphicsMagick.scaleImage(originalImage, originalImage, scaleSize); // 中图
	 * String middeImage = nwFile.getFilePath() + File.separator +
	 * nwFile.getFileID() + "_midde." + nwFile.getFileType();
	 * GraphicsMagick.zoomImage(originalImage, middeImage, 600, null); // 小图
	 * String smallImage = nwFile.getFilePath() + File.separator +
	 * nwFile.getFileID() + "_small." + nwFile.getFileType();
	 * GraphicsMagick.zoomImage(originalImage, smallImage, 300, null);
	 * nwFileDao.saveFile(nwFile); return nwFile.getFileID(); } else { String
	 * UUIDStr = "pr_" + UUIDUtil.getStringUUid(); NWFile nwFile =
	 * NWFileGenerator.privateNWFilegenerate(file, UUIDStr); //
	 * 原始图片打上水印，temp图片不打水印 String originalImage = nwFile.getFilePath() +
	 * File.separator + nwFile.getFileID() + "." + nwFile.getFileType();
	 * GraphicsMagick.addImgText(originalImage, text);// 已经打上水印 // 压缩下图片大小
	 * GraphicsMagick.scaleImage(originalImage, originalImage, scaleSize); // 中图
	 * String middeImage = nwFile.getFilePath() + File.separator +
	 * nwFile.getFileID() + "_midde." + nwFile.getFileType();
	 * GraphicsMagick.zoomImage(originalImage, middeImage, 600, null); // 小图
	 * String smallImage = nwFile.getFilePath() + File.separator +
	 * nwFile.getFileID() + "_small." + nwFile.getFileType();
	 * GraphicsMagick.zoomImage(originalImage, smallImage, 300, null);
	 * nwFileDao.saveFile(nwFile); return nwFile.getFileID(); } } return null; }
	 */

	/**
	 * 保存图片打图片水印[默认牛娃水印模板]
	 */
	@Override
	public String saveImageWatermark(FileSystemEnum fileSystemEnum, File file)
			throws Exception {
		if (null == fileSystemEnum) {
			return null;
		}
		if (isImageFile(getFileType(file))) {
			if (fileSystemEnum == FileSystemEnum.PUBLIC) { // 公共
				String UUIDStr = "pl_" + UUIDUtil.getStringUUid();
				NWFile nwFile = NWFileGenerator.publicNWFilegenerate(file,
						UUIDStr);
				// 原始图片打上水印，temp图片不打水印
				String originalImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "." + nwFile.getFileType();
				ImageMagick.waterMark(waterImagePath, originalImage,
						originalImage, waterSize, nwFile.getFileType());// 后面两个参数是位置和透明度1.00-0.01
				// 压缩下图片大小
				ImageMagick.scaleImage(originalImage, originalImage, scaleSize);
				// 中图
				String middeImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_midde." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, middeImage, 600, null);
				// 小图
				String smallImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_small." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, smallImage, 300, null);
				nwFileDao.saveFile(nwFile);
				return nwFile.getFileID();
			} else {
				String UUIDStr = "pr_" + UUIDUtil.getStringUUid();
				NWFile nwFile = NWFileGenerator.privateNWFilegenerate(file,
						UUIDStr);
				// 原始图片打上水印，temp图片不打水印
				String originalImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "." + nwFile.getFileType();
				ImageMagick.waterMark(waterImagePath, originalImage,
						originalImage, waterSize, nwFile.getFileType()); // 后面两个参数是位置和透明度1.00-0.01
				// 压缩下图片大小
				ImageMagick.scaleImage(originalImage, originalImage, scaleSize);
				// 中图
				String middeImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_midde." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, middeImage, 600, null);
				// 小图
				String smallImage = nwFile.getFilePath() + File.separator
						+ nwFile.getFileID() + "_small." + nwFile.getFileType();
				ImageMagick.zoomImage(originalImage, smallImage, 300, null);
				nwFileDao.saveFile(nwFile);
				return nwFile.getFileID();
			}
		}
		return null;

	}

	private Boolean isImageFile(String fileName) {
		Boolean flag = false;
		// 常用六种格式
		String[] splitS = new String[] { "bmp", "jpg", "gif", "png", "jpeg",
				"psd" };
		for (String split : splitS) {
			if (split.equals(fileName)) {
				flag = true;
			}
		}
		return flag;
	}

	private String getFileType(File file) {
		return file.getName().substring(file.getName().lastIndexOf(".") + 1);
	}

	@Override
	public NWFile getDBFileInfo(String fileID) throws Exception {
		NWFile nwFile = nwFileDao.getFile(fileID);
		return nwFile;
	}
}
